package com.quectel.core.module.entranceguard.service.impl;


import com.quectel.constant.global.SystemConstants;
import com.quectel.core.constants.RedisCacheConstants;
import com.quectel.core.module.device.dto.DeviceDto;
import com.quectel.core.module.device.service.DeviceService;
import com.quectel.core.module.entranceguard.dao.EntranceGuardVisitorApplyRecordDao;
import com.quectel.core.module.entranceguard.dto.EntranceGuardVisitorApplyRecordDto;
import com.quectel.core.module.entranceguard.dto.VisitorDto;
import com.quectel.core.module.entranceguard.entity.EntranceGuardVisitorApplyRecordEntity;
import com.quectel.core.module.entranceguard.service.EntranceGuardVisitorApplyRecordService;
import com.quectel.core.module.entranceguard.service.VisitorService;
import com.quectel.core.module.village.dto.VillageRoomDto;
import com.quectel.core.module.village.service.VillageRoomService;
import com.quectel.util.common.CopyUtils;
import com.quectel.util.common.JacksonUtils;
import com.quectel.util.common.MapUtils;
import com.quectel.util.kit.CacheKit;
import com.quectel.util.kit.Snowflake;
import com.quectel.util.mybatis.MyBatisPlusUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author rananxin
 * @date 2021-12-24 10:46:50
 */
@DubboService
public class EntranceGuardVisitorApplyRecordServiceImpl implements EntranceGuardVisitorApplyRecordService {

    private static final Logger LOGGER = LoggerFactory.getLogger(EntranceGuardVisitorApplyRecordServiceImpl.class);

    private static final String ENTRANCE_GUARD_VISITOR_APPLY_RECORD_CACHE_BY_ID = RedisCacheConstants.PROJECT_NAME + "ENTRANCE_GUARD_VISITOR_APPLY_RECORD_CACHE_BY_ID:";

    @Autowired
    private EntranceGuardVisitorApplyRecordDao entranceGuardVisitorApplyRecordDao;
    @Autowired
    private VillageRoomService villageRoomService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private VisitorService visitorService;

    @Override
    public EntranceGuardVisitorApplyRecordDto selectCacheById(Long id) {
        return CacheKit.cacheToRedis(
                () -> selectById(id),
                ENTRANCE_GUARD_VISITOR_APPLY_RECORD_CACHE_BY_ID + id,

                SystemConstants.NOT_NULL_CACHE_EXPIRE_SECONDS
        );
    }

    @Override
    public EntranceGuardVisitorApplyRecordDto selectById(Long id) {
        EntranceGuardVisitorApplyRecordEntity entity = entranceGuardVisitorApplyRecordDao.selectById(id);
        return paddingField(CopyUtils.copyObj(entity, EntranceGuardVisitorApplyRecordDto.class));
    }

    @Override
    public List<EntranceGuardVisitorApplyRecordDto> queryList(Map<String, Object> params) {
        visitorConditionFill(params);

        List<EntranceGuardVisitorApplyRecordEntity> list = entranceGuardVisitorApplyRecordDao.queryList(params);
        List<EntranceGuardVisitorApplyRecordDto> result = CopyUtils.copyList(list, EntranceGuardVisitorApplyRecordDto.class);
        result.forEach(this::paddingField);
        return result;
    }

    private void visitorConditionFill(Map<String, Object> params) {
        Map<String, Object> visitorQuery = new HashMap<>();
        visitorQuery.put("name", params.get("visitorName"));
        visitorQuery.put("mobile", params.get("visitorMobile"));
        if (!MapUtils.allStrValueIsEmpty(visitorQuery)) {
            List<VisitorDto> visitorDtos = visitorService.queryList(visitorQuery);
            params.put("visitorIds", visitorDtos.stream().map(VisitorDto::getId).toArray());
        }
    }


    private EntranceGuardVisitorApplyRecordDto paddingField(EntranceGuardVisitorApplyRecordDto dto) {
        if (dto != null) {
            VillageRoomDto villageRoomDto = villageRoomService.selectById(dto.getRoomId());
            dto.setVillageRoom(villageRoomDto);

            if (StringUtils.isNotBlank(dto.getDeviceIds())) {
                List<DeviceDto> deviceDtos = deviceService.queryList(new HashMap<String, Object>() {
                    {
                        put("ids", JacksonUtils.parseArray(dto.getDeviceIds(), Long.class).stream().toArray());
                    }
                });
                dto.setAuthDevices(deviceDtos);
            }

            VisitorDto visitorDto = visitorService.selectById(dto.getVisitorId());
            dto.setVisitor(visitorDto);
        }
        return dto;
    }

    @Override
    public int queryTotal(Map<String, Object> params) {
        visitorConditionFill(params);
        return entranceGuardVisitorApplyRecordDao.queryTotal(params);
    }

    @Override
    public Long save(EntranceGuardVisitorApplyRecordDto dto) {
        EntranceGuardVisitorApplyRecordEntity entity = CopyUtils.copyObj(dto, EntranceGuardVisitorApplyRecordEntity.class);
        entity.setId(Snowflake.nextId());
        entranceGuardVisitorApplyRecordDao.insert(entity);
        return entity.getId();
    }

    @Override
    public void updateById(EntranceGuardVisitorApplyRecordDto dto) {
        EntranceGuardVisitorApplyRecordEntity entity = CopyUtils.copyObj(dto, EntranceGuardVisitorApplyRecordEntity.class);
        entranceGuardVisitorApplyRecordDao.updateById(entity);
        CacheKit.invalidRedisCache(ENTRANCE_GUARD_VISITOR_APPLY_RECORD_CACHE_BY_ID + dto.getId());
    }

    @Override
    public void updateAllColumnById(EntranceGuardVisitorApplyRecordDto dto) {
        EntranceGuardVisitorApplyRecordEntity entity = CopyUtils.copyObj(dto, EntranceGuardVisitorApplyRecordEntity.class);


        MyBatisPlusUtils.updateAllColumnById(entity, entranceGuardVisitorApplyRecordDao);

        CacheKit.invalidRedisCache(ENTRANCE_GUARD_VISITOR_APPLY_RECORD_CACHE_BY_ID + dto.getId());
    }

    @Override
    public void deleteById(Long id) {
        entranceGuardVisitorApplyRecordDao.deleteById(id);

        CacheKit.invalidRedisCache(ENTRANCE_GUARD_VISITOR_APPLY_RECORD_CACHE_BY_ID + id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] ids) {
        for (Long id : ids) {
            deleteById(id);
        }
    }
}
